using AppToolKit.Core.Logging;
using Common.Logging;
using System;
using System.Collections.Generic;
using System.IO;
using System.Xml;
namespace AppToolKit.Core.Xml
{
	public class XmlParser : IDisposable
	{
		private class StackItem
		{
			public string Element
			{
				get;
				set;
			}
			public object Instance
			{
				get;
				set;
			}
		}
		private static ILog logger_ = LogManager.GetLogger(DefaultLogger.LOGGER_NAME);
		private XmlReader rd_;
		private Dictionary<string, ElementHandler> map_;
		private string current_element_ = null;
		private Stack<XmlParser.StackItem> stack_ = new Stack<XmlParser.StackItem>();
		protected Dictionary<string, ElementHandler> HandlerMap
		{
			get
			{
				if (this.map_ == null)
				{
					this.map_ = new Dictionary<string, ElementHandler>();
				}
				return this.map_;
			}
		}
		public XmlParser(string xmlFile)
		{
			this.rd_ = XmlReader.Create(xmlFile);
		}
		public XmlParser(TextReader reader)
		{
			this.rd_ = XmlReader.Create(reader);
		}
		public void OnStartElement(object parent, string element, string value)
		{
			if (this.HandlerMap.ContainsKey(element))
			{
				object instance = this.HandlerMap[element].OnStartElement(parent);
				if (!this.rd_.IsEmptyElement)
				{
					XmlParser.StackItem item = new XmlParser.StackItem
					{
						Element = element,
						Instance = instance
					};
					this.stack_.Push(item);
				}
				this.GetAttributes(instance, element, this.HandlerMap[element]);
			}
			else
			{
				XmlParser.logger_.Debug(string.Format("{0}找不到对应的处理过程", element));
			}
		}
		public void OnElement(string element, string value)
		{
			if (!this.HandlerMap.ContainsKey(element))
			{
				string element2 = this.stack_.Peek().Element;
				if (element2 != element)
				{
					string message = string.Format("Element({0})没有闭合", element2);
					if (XmlParser.logger_.IsErrorEnabled)
					{
						XmlParser.logger_.Error(message);
					}
					throw new XmlParserException(message);
				}
				object instance = this.stack_.Peek().Instance;
				this.HandlerMap[element].OnElement(instance, value);
			}
		}
		public void OnEndElement(string element, string value)
		{
			if (this.HandlerMap.ContainsKey(element))
			{
				string element2 = this.stack_.Peek().Element;
				if (element2 != element)
				{
					string message = string.Format("Element({0})没有闭合", element2);
					if (XmlParser.logger_.IsErrorEnabled)
					{
						XmlParser.logger_.Error(message);
					}
					throw new XmlParserException(message);
				}
				XmlParser.StackItem stackItem = this.stack_.Pop();
				object parent = null;
				if (this.stack_.Count > 0)
				{
					parent = this.stack_.Peek().Instance;
				}
				this.HandlerMap[element].OnEndElement(parent, stackItem.Instance);
			}
		}
		public void GetAttributes(object instance, string element, ElementHandler handler)
		{
			if (this.rd_.HasAttributes)
			{
				XmlParser.logger_.Debug("Attributes of <" + this.rd_.Name + ">");
				while (this.rd_.MoveToNextAttribute())
				{
					handler.OnAttribute(instance, element, this.rd_.Name, this.rd_.Value);
				}
			}
		}
		public bool Read()
		{
			return this.rd_.Read();
		}
		public void Parse(object parentNode)
		{
			while (this.Read())
			{
				XmlNodeType nodeType = this.rd_.NodeType;
				switch (nodeType)
				{
				case XmlNodeType.Element:
					{
						if (XmlParser.logger_.IsDebugEnabled)
						{
							XmlParser.logger_.Debug(string.Format("<{0}>", this.rd_.Name));
						}
						object parent;
						if (this.stack_.Count > 0)
						{
							parent = this.stack_.Peek().Instance;
						}
						else
						{
							parent = parentNode;
						}
						this.OnStartElement(parent, this.rd_.Name, this.rd_.Value);
						break;
					}

				case XmlNodeType.Attribute:
					if (XmlParser.logger_.IsDebugEnabled)
					{
						XmlParser.logger_.Debug(string.Format("[{0}]", this.rd_.Value));
					}
					break;

				default:
					if (nodeType == XmlNodeType.EndElement)
					{
						if (XmlParser.logger_.IsDebugEnabled)
						{
							XmlParser.logger_.Debug(string.Format("</{0}/>", this.rd_.Name));
						}
						this.OnEndElement(this.rd_.Name, this.rd_.Value);
					}
					break;
				}
			}
		}
		public void RegisterHanlder(string element, ElementHandler handler)
		{
			this.HandlerMap.Add(element, handler);
		}
		public void Dispose()
		{
			this.rd_.Close();
		}
	}
}
